package com.barradata.app0624.modules.extra

import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Group
import com.barradata.BuildConfig
import com.barradata.R
import com.barradata.app0624.api.ApiService
import com.barradata.app0624.modules.camera.CameraActivity
import com.barradata.app0624.modules.camera.CameraCallbackEvent
import com.barradata.app0624.modules.web.EventType
import com.barradata.app0624.modules.web.WebCallbackEvent
import com.barradata.common.base.BaseActivity
import com.barradata.common.rxbinding.clickV
import com.barradata.common.rxbus.RxBus
import com.barradata.common.utils.ToastUtils
import com.barradata.common.view.AlertDialogFragment
import com.example.hfiveandaplication.bean.IdentityData
import com.squareup.picasso.Picasso
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.Observable
import io.reactivex.functions.Consumer
import kotlinx.android.synthetic.main.extra_info_activity.*

/**
 * Author:    WuNan
 * Email:     wunan@barradata.com
 * Created:   2019/7/9 23:52
 **/
//TODO: 补充图片待改造为 RecyclerView
class ExtraInfoActivity : BaseActivity() {
    companion object {
        fun actionStart(context: Context) {
            context.startActivity(Intent(context, ExtraInfoActivity::class.java))
        }

        private val REQUEST_PERMISSION = arrayOf(Manifest.permission.CAMERA,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
        /**
         * 必须上传图片的个数
         */
        private const val MUST_UPLOAD_PHOTO_COUNT = 3
    }

    private val rxPermissions = RxPermissions(this)
    /**
     * 保证 buttons 数组内元素的顺序与设计图一致即可自动匹配相片类型
     */
    private lateinit var buttons: Array<ConstraintLayout>

    /**
     * 已上传图片个数
     */
    private var uploadPhotoCount: Int = 0

    private val uploadImageInfoArr: MutableList<IdentityData.ImageInfoBean> = mutableListOf()

    override fun getLayoutId() = R.layout.extra_info_activity

    override fun initView() {
        setupActionBar(toolbar)
        requestPermission()
        prepareButtonArray()
        setupPhotoButtons()
        setupNextButton()
        registerCameraCallback()
    }

    override fun onBackPressed() {
        super.onBackPressed()
        RxBus.post(WebCallbackEvent(EventType.FROM_CANCEL))
    }

    private fun setupNextButton() {
        next_button.clickV().filter { it.alpha == 1f }.subscribe {
            ApiService.updateAdditionalInfo(uploadImageInfoArr).doOnSubscribe { showLoadingView() }
                    .doFinally { dismissLoadingView() }
                    .subscribe({
                        if (it.isRel && it.status == 200) {
                            RxBus.post(WebCallbackEvent(EventType.FROM_EXTRA_INFO))
                            finish()
                        } else {
                            ToastUtils.showShort(it.message)
                        }
                    }, {
                        ToastUtils.showShort(R.string.network_error)
                    }).autoClean()
        }?.autoClean()
    }

    private fun prepareButtonArray() {
        buttons = arrayOf(tax_layout, baoxiandan_layout, house_holder_layout
                , cunzhe_layout, mingpian_layout, jiashizheng_layout,
                chepai_layout, xinyongka_layout, work_layout)
        house_holder_layout.tag = 1
        work_layout.tag = 1
        tax_layout.tag = 1
    }

    private fun registerCameraCallback() {
        RxBus.toObservable(CameraCallbackEvent::class.java)
                .filter {
                    listOf(ApiService.UploadImageType.ID_CARD, ApiService.UploadImageType.ID_CARD_WITH_PORTRAIT,
                            ApiService.UploadImageType.TAX, ApiService.UploadImageType.INSURANCE_ORDER,
                            ApiService.UploadImageType.HOUSEHOLD_REGISTER, ApiService.UploadImageType.PASSBOOK,
                            ApiService.UploadImageType.BUSINESS_CARD, ApiService.UploadImageType.DRIVE_CARD,
                            ApiService.UploadImageType.CAR_NO, ApiService.UploadImageType.LOAN_USAGE,
                            ApiService.UploadImageType.CREDIT_CARD, ApiService.UploadImageType.WORK_CARD
                    ).contains(it.photoType)
                }
                .subscribe {
                    uploadImage(it)
                }.autoClean()
    }

    private fun updateNextButton() {
        if (uploadPhotoCount < MUST_UPLOAD_PHOTO_COUNT) {
            next_button.alpha = 0.55f
        } else {
            next_button.alpha = 1f
        }
    }

    private fun uploadImage(callbackEvent: CameraCallbackEvent) {
        ApiService.uploadImage(callbackEvent.photoType, callbackEvent.photoFile)
                .doOnSubscribe { showLoadingView() }
                .doFinally { dismissLoadingView() }
                .subscribe({
                    if (it.isRel) {
                        // 隐藏照片提示前景
                        val buttonLayout = buttons[getButtonIndex(callbackEvent.photoType)]
                        hideHintGroup(buttonLayout)
                        // 加载照片
                        val imageView = getButtonImageView(buttonLayout)
                        val imageInfo = it.data.imageInfo
                        uploadImageInfoArr.add(imageInfo)
                        uploadPhotoCount += (buttonLayout.tag as Int)
                        Picasso.get().load(imageInfo.imageUrl).fit().into(imageView)
                    } else {
                        ToastUtils.showShort(it.message)
                    }
                    updateNextButton()
                }, {
                    it.printStackTrace()
                    ToastUtils.showShort(R.string.network_error)
                }).autoClean()
    }

    private fun setupPhotoButtons() {
        Observable.fromArray(*buttons).map { it.clickV() }
                .filter { checkPermission() }
                .flatMap { it }
                .map { it as ViewGroup }
                .subscribe {
                    CameraActivity.actionStart(this, getPhotoType(buttons.indexOf(it)))
                }.autoClean()
    }

    /**
     * xml 中 每个 cameraViewGroup 中的最后一个元素均为约束布局 Group 组件，
     * 此处先采用计算的方式得到该 Group 组件，然后将其隐藏
     *
     * @param cameraGroup 相机组件 ViewGroup
     *
     */
    private fun hideHintGroup(cameraGroup: ViewGroup) {
        @Suppress("CAST_NEVER_SUCCEEDS")
        val group = cameraGroup.getChildAt(cameraGroup.childCount - 1) as Group
        group.visibility = View.GONE
        cameraGroup.isEnabled = false
    }

    /**
     * xml 中 每个 cameraViewGroup 中的首个元素均为 ImageView 组件，
     * 此处先采用计算的方式得到该 ImageView 组件
     *
     * @param cameraGroup 相机组件 ViewGroup
     *
     */
    @Suppress("CAST_NEVER_SUCCEEDS")
    private fun getButtonImageView(cameraGroup: ViewGroup): ImageView {
        return cameraGroup.getChildAt(0) as ImageView
    }

    /**
     * 根据按钮在数组中的索引值，得到其对应的相片类型
     *
     * @param buttonIndex 相片数组按钮的索引
     *
     * 根据服务端 API 定义，当前页面内所上传的图片是从照片类型 3 开始计数的，因此在枚举中取值时，
     * 需使用 buttonIndex + 3 来作为实际的索引值来进行取值
     *
     * 另外，因 buttons 数组中索引值 7 的图片类型对应 API 定义中的 第 11 个类型，因此索引 7 开始取值改为 buttonIndex + 4
     *
     */
    @Deprecated("此处的魔数待改造至 RecyclerView 后弃用")
    private fun getPhotoType(buttonIndex: Int): ApiService.UploadImageType {
        if (buttonIndex < 7)
            return ApiService.UploadImageType.values()[buttonIndex + 3]
        else {
            return ApiService.UploadImageType.values()[buttonIndex + 4]
        }
    }

    /**
     * 根据枚举类型，获取枚举值在当前页面的按钮数组中的索引值
     *
     * @param type 枚举中对应的照片类型
     *
     * 根据服务端 API 定义，当前页面内所上传的图片是从照片类型 3 开始计数的，因此在将枚举值转化为 button 在按钮数组中的索引值时，
     * 需使用 indexOf(type) - 3 来作为求得的索引值
     *
     * 因 buttons 数组的后两个按钮跳过了 API 定义中的 LOAN_USAGE,因此对于这 CREDIT_CARD/WORK_CARD 这两个类型，需采用 indexOf(type) - 4
     *
     */
    @Deprecated("此处的魔数待改造至 RecyclerView 后弃用")
    private fun getButtonIndex(type: ApiService.UploadImageType): Int {
        if (listOf(ApiService.UploadImageType.CREDIT_CARD, ApiService.UploadImageType.WORK_CARD).contains(type)) {
            return ApiService.UploadImageType.values().indexOf(type) - 4
        }
        return ApiService.UploadImageType.values().indexOf(type) - 3
    }

    //TODO 权限相关函数待抽象为可复用组件
    private fun checkPermission(): Boolean {
        REQUEST_PERMISSION.iterator().forEach {
            if (!rxPermissions.isGranted(it)) {
                requestPermission()
                return false
            }
        }
        return true
    }

    private fun requestPermission() {
        rxPermissions.requestEach(*REQUEST_PERMISSION).subscribe {
            if (it.granted) {
                return@subscribe
            }
            val singleButtonAction: ()->Unit
            if (it.shouldShowRequestPermissionRationale) {
                singleButtonAction =  { requestPermission() }
            } else {
                singleButtonAction =  { go2Setting() }
            }
            ToastUtils.showShort(R.string.get_permission_failure_hint)
            AlertDialogFragment.create(singleButtonAction).setCancelAble(false)
                    .setTitle(getString(R.string.get_permission_failure_hint))
                    .show(this)
        }.autoClean()
    }

    private fun go2Setting() {
        val localIntent = Intent()
        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
        localIntent.data = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
        startActivity(localIntent)
    }

    override fun finish() {
        super.finish()
        overridePendingTransition(0,R.anim.fade_out)
    }
}